home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / lpc10 / voice.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  11KB  |  360 lines

  1. /***************************************************************************   
  2. *
  3. *    VOICIN Version 52
  4. *
  5. ***************************************************************************
  6. *
  7. *     Voicing Detection (VOICIN) makes voicing decisions for each half
  8. *   frame of input speech.  Tentative voicing decisions are made two frames
  9. *   in the future (2F) for each half frame.  These decisions are carried
  10. *   through one frame in the future (1F) to the present (P) frame where
  11. *   they are examined and smoothed, resulting in the final voicing
  12. *   decisions for each half frame. 
  13. *     The voicing parameter (signal measurement) column vector (VALUE)
  14. *   is based on a rectangular window of speech samples determined by the
  15. *   window placement algorithm.  The voicing parameter vector contains the
  16. *   AMDF windowed maximum-to-minimum ratio, the zero crossing rate, energy
  17. *   measures, reflection coefficients, and prediction gains.  The voicing
  18. *   window is placed to avoid contamination of the voicing parameter vector
  19. *   with speech onsets. 
  20. *     The input signal is then classified as unvoiced (including
  21. *   silence) or voiced.  This decision is made by a linear discriminant
  22. *   function consisting of a dot product of the voicing decision
  23. *   coefficient (VDC) row vector with the measurement column vector
  24. *   (VALUE).  The VDC vector is 2-dimensional, each row vector is optimized
  25. *   for a particular signal-to-noise ratio (SNR).  So, before the dot
  26. *   product is performed, the SNR is estimated to select the appropriate
  27. *   VDC vector. 
  28. *     The smoothing algorithm is a modified median smoother.  The
  29. *   voicing discriminant function is used by the smoother to determine how
  30. *   strongly voiced or unvoiced a signal is.  The smoothing is further
  31. *   modified if a speech onset and a voicing decision transition occur
  32. *   within one half frame.  In this case, the voicing decision transition
  33. *   is extended to the speech onset.  For transmission purposes, there are
  34. *   constraints on the duration and transition of voicing decisions.  The
  35. *   smoother takes these constraints into account. 
  36. *     Finally, the energy estimates are updated along with the dither
  37. *   threshold used to calculate the zero crossing rate (ZC).
  38. *
  39. *  Inputs:
  40. *   VWIN      - Voicing window limits
  41. *   INBUF     - Input speech buffer
  42. *   LPBUF     - Low-pass filtered speech buffer
  43. *   BUFLIM    - INBUF and LPBUF limits
  44. *   HALF      - Present analysis half frame number
  45. *   MINAMD    - Minimum value of the AMDF
  46. *   MAXAMD    - Maximum value of the AMDF
  47. *   MINTAU    - Pointer to the lag of the minimum AMDF value
  48. *   IVRC(2)   - Inverse filter's RC's
  49. *   OBOUND    - Onset boundary descriptions
  50. *   AF          - The analysis frame number
  51. *  Output:
  52. *   VOIBUF(2,0:AF) - Buffer of voicing decisions
  53. *  Internal:
  54. *   QS          - Ratio of preemphasized to full-band energies
  55. *   RC1       - First reflection coefficient
  56. *   AR_B      - Product of the causal forward and reverse pitch prediction gains
  57. *   AR_F      - Product of the noncausal forward and rev. pitch prediction gains
  58. *   ZC          - Zero crossing rate
  59. *   DITHER    - Zero crossing threshold level
  60. *   MAXMIN    - AMDF's 1 octave windowed maximum-to-minimum ratio
  61. *   MINPTR    - Location  of minimum AMDF value
  62. *   NVDC      - Number of elements in each VDC vector
  63. *   NVDCL     - Number of VDC vectors
  64. *   VDCL      - SNR values corresponding to the set of VDC's
  65. *   VDC       - 2-D voicing decision coefficient vector
  66. *   VALUE(9)  - Voicing Parameters
  67. *   VOICE(2,3)- History of LDA results
  68. *   LBE       - Ratio of low-band instantaneous to average energies
  69. *   FBE       - Ratio of full-band instantaneous to average energies
  70. *   LBVE      - Low band voiced energy
  71. *   LBUE      - Low band unvoiced energy
  72. *   FBVE      - Full band voiced energy
  73. *   FBUE      - Full band unvoiced energy
  74. *   OFBUE     - Previous full-band unvoiced energy
  75. *   OLBUE     - Previous low-band unvoiced energy
  76. *   REF       - Reference energy for initialization and DITHER threshold
  77. *   SNR       - Estimate of signal-to-noise ratio
  78. *   SNR2      - Estimate of low-band signal-to-noise ratio
  79. *   SNRL      - SNR level number
  80. *   OT          - Onset transition present
  81. *   VSTATE    - Decimal interpretation of binary voicing classifications
  82. *   FIRST     - First call flag
  83. */
  84.  
  85. #include <stdio.h>
  86. #include "vcomm.ch"
  87. #include "contrl.ch"
  88. #include "lpcdefs.h"
  89. #include <math.h>
  90.  
  91. voicin( vwin, inbuf, lpbuf, half, minamd, maxamd, mintau, ivrc, obound, voibuf)
  92. int vwin[2][AF], half, mintau;
  93. float minamd, maxamd, ivrc[2];
  94. float *inbuf;
  95. float *lpbuf;
  96. int *obound, voibuf[2][AF+1];
  97. {
  98. int zc, lbe, fbe;
  99. int i, snrl;
  100. static int vstate=0;
  101. static float dither=20;
  102. static float snr;
  103. float snr2;
  104. static float maxmin;
  105. float qs, rc1, ar_b;
  106. float ar_f;
  107. static float voice[2][3];
  108. float value[9];
  109. short ot=0;
  110.  
  111. /*   Declare and initialize filters:    */
  112.  
  113. static int lbve, lbue, fbve, fbue, ofbue, olbue;
  114. static int sfbue, slbue=0;
  115. int ref= 3000;
  116. static short first=1;
  117.  
  118.  
  119. if (first) {
  120.     lbve = ref;
  121.     fbve = ref;
  122.     fbue = ref/16;
  123.     ofbue = ref/16;
  124.     lbue = ref/32;
  125.     olbue = ref/32;
  126.     snr = 64*(fbve/fbue);
  127.     first = 0;
  128.     vdcl[0] = 600;
  129.     vdcl[1] = 450;
  130.     vdcl[2] = 300;
  131.     vdcl[3] = 200;
  132.     vdcl[4] = 6*0;
  133.     
  134.     for(i=0;i<3;i++)    {
  135.         voice[1][i] = 0.0;
  136.         voice[0][i] = 0.0;
  137.     }
  138.     
  139. }
  140.  
  141. /*   The VOICE array contains the result of the linear discriminant function 
  142. *   (analog values).  The VOIBUF array contains the hard-limited binary 
  143. *   voicing decisions.    The VOICE and VOIBUF arrays, according to FORTRAN 
  144. *   memory allocation, are addressed as:
  145. *
  146. *       (half-frame number, future-frame number)
  147. *
  148. *       |   Past    |  Present  |  Future1  |  Future2  |
  149. *       | 1,0 | 2,0 | 1,1 | 2,1 | 1,2 | 2,2 | 1,3 | 2,3 |  --->  time
  150. *
  151. *   Update linear discriminant function history each frame:        */
  152.  
  153. if (half == 1) {
  154.     voice[0][0]=voice[0][1];
  155.     voice[1][0]=voice[1][1];
  156.     voice[0][1]=voice[0][2];
  157.     voice[1][1]=voice[1][2];
  158.     maxmin = maxamd/mmax(minamd,1.);
  159. }
  160.  
  161. /*   Calculate voicing parameters twice per frame:    */
  162.  
  163. vparms( vwin, inbuf, lpbuf, half, &dither, mintau, &zc, &lbe, &fbe, &qs, &rc1, &ar_b, &ar_f );
  164.  
  165. /*   Estimate signal-to-noise ratio to select the appropriate VDC vector.
  166. *   The SNR is estimated as the running average of the ratio of the
  167. *   running average full-band voiced energy to the running average
  168. *   full-band unvoiced energy. SNR filter has gain of 63.    */
  169.  
  170. snr = L_nint( 63*( snr + fbve/(float)(mmax(fbue,1)) )/64.);
  171. snr2 = (snr*fbue)/mmax(lbue,1);
  172.  
  173. /*   Quantize SNR to SNRL according to VDCL thresholds.*/
  174.  
  175. /*DO SNRL = 1, NVDCL-1 */
  176. for (snrl=1;snrl<nvdcl;snrl++)    {
  177.     if (snr2 > vdcl[snrl-1]) break;
  178. }
  179. /*    (Note:    SNRL = NVDCL Here)    */
  180.  
  181. /*   Linear discriminant voicing parameters:    */
  182. value[0] = maxmin;
  183. value[1] = (float)(lbe)/mmax(lbve,1);
  184. value[2] = zc;
  185. value[3] = rc1;
  186. value[4] = qs;
  187. value[5] = ivrc[2];
  188. value[6] = ar_b;
  189. value[7] = ar_f;
  190. value[8] = 0.0;
  191.  
  192. /*   Evaluation of linear discriminant function:    */
  193.  
  194. voice[half-1][2] = vdc[9][snrl-1];
  195.  
  196. for(i=1;i<10;i++)    {
  197.     voice[half-1][2] += vdc[i-1][snrl-1]*value[i-1];
  198. }
  199.  
  200. /*   Classify as voiced if discriminant > 0, otherwise unvoiced
  201. *   Voicing decision for current half-frame:  1 = Voiced; 0 = Unvoiced    */
  202.  
  203. if (voice[half-1][2] > 0.0) 
  204.     voibuf[half-1][3]=1;
  205. else
  206.     voibuf[half-1][3]=0;
  207.  
  208. /*   Skip voicing decision smoothing in first half-frame:    */
  209.  
  210. if (half != 1) {
  211. /*   Voicing decision smoothing rules (override of linear combination):
  212. *
  213. *    Unvoiced half-frames:  At least two in a row.
  214. *    --------------------
  215. *
  216. *    Voiced half-frames:    At least two in a row in one frame.
  217. *    -------------------    Otherwise at least three in a row.
  218. *                   (Due to the way transition frames are encoded)
  219. *
  220. *    In many cases, the discriminant function determines how to smooth.
  221. *    In the following chart, the decisions marked with a * may be overridden.
  222. *
  223. *   Voicing override of transitions at onsets:
  224. *    If a V/UV or UV/V voicing decision transition occurs within one-half
  225. *    frame of an onset bounding a voicing window, then the transition is
  226. *    moved to occur at the onset.
  227. *
  228. *    P    1F
  229. *    -----    -----
  230. *    0   0    0   0
  231. *    0   0    0*  1    (If there is an onset there)
  232. *    0   0    1*  0*    (Based on 2F and discriminant distance)
  233. *    0   0    1   1
  234. *    0   1*    0   0    (Always)
  235. *    0   1*    0*  1    (Based on discriminant distance)
  236. *    0*  1    1   0*    (Based on past, 2F, and discriminant distance)
  237. *    0   1*    1   1    (If there is an onset there)
  238. *    1   0*    0   0    (If there is an onset there)
  239. *    1   0    0   1
  240. *    1   0*    1*  0    (Based on discriminant distance)
  241. *    1   0*    1   1    (Always)
  242. *    1   1    0   0
  243. *    1   1    0*  1*    (Based on 2F and discriminant distance)
  244. *    1   1    1*  0    (If there is an onset there)
  245. *    1   1    1   1
  246. *
  247. *   Determine if there is an onset transition between P and 1F.
  248. *   OT (Onset Transition) is true if there is an onset between 
  249. *   P and 1F but not after 1F.
  250. */
  251.  
  252. /*OT = (AND(OBOUND(1), 2) .NE. 0 .OR. OBOUND(2) .EQ. 1) .AND. AND(OBOUND(3), 1) .EQ. 0 */
  253. ot = ((obound[1] & 2) != 0 || obound[2] == 1) && (obound[3] & 1) == 0;
  254.  
  255. /*   Multi-way dispatch on voicing decision history:    */
  256.  
  257. vstate = voibuf[0][1]*8 + voibuf[1][1]*4 + voibuf[0][2]*2 + voibuf[1][2];
  258. /*    GOTO (99,1,2,99,4,5,6,7,8,99,10,11,99,13,14,99) VSTATE+1    */
  259.  
  260. /*if(count==9) printf("vstate = %d\n",vstate);*/
  261.  
  262. switch(vstate+1)    {
  263.     case 1:
  264.         break;
  265.     case 2:
  266.         if (ot && voibuf[0][3] == 1) voibuf[0][2] = 1;
  267.         break;
  268.     case 3:
  269.         if (voibuf[0][3] == 0 || voice[0][1] < -voice[1][1]) 
  270.             voibuf[0][2] = 0;
  271.         else
  272.             voibuf[1][2] = 1;
  273.         break;
  274.     case 4:
  275.         break;
  276.     case 5:
  277.         voibuf[1][1] = 0;
  278.         break;
  279.     case 6:
  280.         if (voice[1][0] < -voice[0][1]) 
  281.             voibuf[1][1] = 0;
  282.         else
  283.             voibuf[0][2] = 1;
  284.         break;
  285.     case 7:
  286.     /*   VOIBUF(2,0) must be 0    */
  287.         if (voibuf[0][0] == 1 || voibuf[0][3] == 1 || voice[1][1] > voice[0][0]) 
  288.             voibuf[1][2] = 1;
  289.         else
  290.             voibuf[0][1] = 1;
  291.         break;
  292.     case 8:
  293.         if (ot) voibuf[1][1] = 0;
  294.         break;
  295.     case 9:
  296.         if (ot) voibuf[1][1] = 1;
  297.         break;
  298.     case 10:
  299.         break;
  300.     case 11:
  301.         if (voice[0][1] <  -voice[1][0]) 
  302.             voibuf[0][2] = 0;
  303.         else
  304.             voibuf[1][1] = 1;
  305.         break;
  306.     case 12:
  307.         voibuf[1][1] = 1;
  308.         break;
  309.     case 13:
  310.         break;
  311.     case 14:
  312.         if ((voibuf[0][3] == 0) && (voice[1][1] < -voice[0][1]) )
  313.             voibuf[1][2] = 0;
  314.         else
  315.             voibuf[0][2] = 1;
  316.         break;
  317.     case 15:
  318.         if (ot && voibuf[0][3] == 0) voibuf[0][2] = 0;
  319.         break;
  320.     default:
  321.         break;
  322. }
  323. } /* (99)*/
  324.  
  325. /*   Now update parameters:
  326. *   ----------------------
  327. *
  328. *   During unvoiced half-frames, update the low band and full band unvoiced
  329. *   energy estimates (LBUE and FBUE) and also the zero crossing
  330. *   threshold (DITHER).  (The input to the unvoiced energy filters is
  331. *   restricted to be less than 10dB above the previous inputs of the
  332. *   filters.)
  333. *   During voiced half-frames, update the low-pass (LBVE) and all-pass 
  334. *   (FBVE) voiced energy estimates.                    */
  335.  
  336. if (voibuf[half-1][3] == 0) {
  337.     sfbue = L_nint(( 63*sfbue + 8*mmin(fbe,3*ofbue) )/64.);
  338.     fbue = sfbue/8;
  339.     ofbue = fbe;
  340.     slbue = L_nint(( 63*slbue + 8*mmin(lbe,3*olbue) )/64.);
  341.     lbue = slbue/8;
  342.         
  343.     olbue = lbe;
  344. }
  345. else{
  346.     lbve = L_nint(( 63*lbve + lbe )/64.);
  347.     fbve = L_nint(( 63*fbve + fbe )/64.);
  348. }
  349.  
  350. /*   Set dither threshold to yield proper zero crossing rates in the
  351. *   presence of low frequency noise and low level signal input.
  352. *   NOTE: The divisor is a function of REF, the expected energies.    */
  353.  
  354. dither = mmin(mmax( 64*sqrt((float)(lbue*lbve)) / ref,1.),20.);
  355.  
  356. /*   Voicing decisions are returned in VOIBUF.    */
  357.  
  358. }
  359.  
  360.